package com.lin.util;

import com.lin.enums.util.ResponseStatusCode;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

/**
 * Http连接工具
 *
 * @author 九分石人, 2019-12-31
 */
@Slf4j
public class HttpConnectionUtil {

    private static String encode = "UTF-8";
    private static String accept = "application/json";
    private static String content_type = "application/json";


    /**
     * 发送Get请求
     *
     * @param url url地址
     * @return 返回的信息
     * @author com.lin, 2019-12-20
     */
    public static String sendGet(String url) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        String result = "";
        try {
            String newUrl = getNewUrlByUrlEncodeParam(url);
            URL realUrl = new URL(newUrl);
            String method = "GET";

            connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod(method);
            connection.setRequestProperty("accept", accept);
            connection.setRequestProperty("content-type", content_type);
            connection.setRequestProperty("Accept-Charset", encode);
            connection.setRequestProperty("contentType", encode);
            connection.connect();

            int responseCode = connection.getResponseCode();
            if (responseCode == ResponseStatusCode.OK.getCode()) {
                inputStream = connection.getInputStream();
            } else {
                inputStream = connection.getErrorStream();
            }
            result = changeInputStream(inputStream, encode);
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            closeConnection(connection, null, inputStream);
        }
        return result;
    }

    /**
     * 发送Post请求
     *
     * @param url  url地址
     * @param body 发送的信息
     * @return 返回的信息
     * @author com.lin, 2019-12-20
     */
    public static String sendPost(String url, String body) {
        HttpURLConnection connection = null;
        Writer out = null;
        InputStream inputStream = null;
        String result = "";
        try {
            String newUrl = getNewUrlByUrlEncodeParam(url);
            URL realUrl = new URL(newUrl);
            String method = "POST";

            connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod(method);
            connection.setRequestProperty("accept", accept);
            connection.setRequestProperty("content-type", content_type);
            connection.setRequestProperty("Accept-Charset", encode);
            connection.setRequestProperty("contentType", encode);
            connection.setDoOutput(true);
            connection.setDoInput(true);
            out = new OutputStreamWriter(connection.getOutputStream(), encode);
            out.write(body);
            out.flush();

            int responseCode = connection.getResponseCode();
            if (responseCode == ResponseStatusCode.OK.getCode()) {
                inputStream = connection.getInputStream();
            } else {
                inputStream = connection.getErrorStream();
            }
            result = changeInputStream(inputStream, encode);
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            closeConnection(connection, out, inputStream);
        }
        return result;
    }

    /**
     * 连接关闭工具
     *
     * @param conn url连接
     * @param out  输出流
     * @param in   输入流
     * @author com.lin, 2019-12-20
     */
    private static void closeConnection(HttpURLConnection conn, Writer out, InputStream in) {
        try {
            if (conn != null) {
                conn.disconnect();
            }
            if (out != null) {
                out.close();
            }
            if (in != null) {
                in.close();
            }
        } catch (IOException ex) {
            log.error(ex.getMessage());
        }
    }

    /**
     * 从输入流获取传输的字符串
     *
     * @param inputStream 输入流
     * @param encode      编码
     * @return 从输入流获取的字符串
     * @author com.lin, 2019-12-20
     */
    private static String changeInputStream(InputStream inputStream,
                                            String encode) {
        // ByteArrayOutputStream 一般叫做内存流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] data = new byte[1024];
        int length;
        String result = "";
        if (inputStream != null) {
            try {
                while ((length = inputStream.read(data)) != -1) {
                    byteArrayOutputStream.write(data, 0, length);
                }
                result = new String(byteArrayOutputStream.toByteArray(), encode);
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
        return result;
    }


    /**
     * UrlEncode URL's Param for resolve。重写Url
     *
     * @param url 原url 包含
     * @return newURL 新的Url
     * @throws UnsupportedEncodingException 编码异常
     * @author com.lin, 2019-12-19
     */
    private static String getNewUrlByUrlEncodeParam(String url) throws UnsupportedEncodingException {
        StringBuilder urlForEncode = new StringBuilder();
        String newUrl;
        if (url.contains("=")) {
            String[] urlBeforeEncode = url.split("=");
            for (int i = 1; i < urlBeforeEncode.length; i++) {
                if (urlBeforeEncode[i].contains("&")) {
                    String[] paramsplit = urlBeforeEncode[i].split("&");
                    URLEncoder.encode(paramsplit[0], encode);
                    urlBeforeEncode[i] = paramsplit[0] + "&" + paramsplit[1];
                }
                if (i == urlBeforeEncode.length - 1) {
                    urlBeforeEncode[i] = URLEncoder.encode(urlBeforeEncode[i], encode);
                }
                urlForEncode.append(urlBeforeEncode[i]);
                if (i != urlBeforeEncode.length - 1) {
                    urlForEncode = urlForEncode.append("=");
                }
            }
            newUrl = urlBeforeEncode[0] + "=" + urlForEncode.toString();
            return newUrl;
        }
        return url;
    }


}
